#include "stm32f10x.h"                  // Device header
#include "Delay.h" 
void GPIOB0_IN(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void GPIOB0_OUT(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//复位DS18B20
void DS18B20_Rst(void)	   
{                 
	GPIOB0_OUT(); 	
    GPIO_ResetBits(GPIOB, GPIO_Pin_0); 	//拉低DQ
    Delay_us(750);    	//拉低750us
    GPIO_SetBits(GPIOB, GPIO_Pin_0); 	//DQ=1 
	Delay_us(15);     	//15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
uint8_t DS18B20_Check(void) 	   
{   
	uint8_t retry=0;
	GPIOB0_IN();	 
    while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0)&&retry<200)
	{
		retry++;
		Delay_us(1);
	};	 
	if(retry>=200)return 1;
	else retry=0;
    while (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0)&&retry<240)
	{
		retry++;
		Delay_us(1);
	};
	if(retry>=240)return 1;	    
	return 0;
}
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
uint8_t DS18B20_Init(void) //初始化
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIOB0_IN();
	GPIOB0_OUT();
	DS18B20_Rst();
	return DS18B20_Check();
}

//从DS18B20读取一个位
//返回值：1/0
uint8_t DS18B20_Read_Bit(void) 	 
{
    uint8_t data;
	GPIOB0_OUT();	
    GPIO_ResetBits(GPIOB, GPIO_Pin_0); 
	Delay_us(2);
    GPIO_SetBits(GPIOB, GPIO_Pin_0);
	GPIOB0_IN();	
	Delay_us(12);
	if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0))data=1;
    else data=0;	 
    Delay_us(50);           
    return data;
}

//从DS18B20读取一个字节
//返回值：读到的数据
uint8_t DS18B20_Read_Byte(void)     
{        
    uint8_t i,j,dat;
    dat=0;
	for (i=1;i<=8;i++) 
	{
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }						    
    return dat;
}

//写一个字节到DS18B20
//dat：要写入的字节
void DS18B20_Write_Byte(uint8_t dat)     
{             
    uint8_t j;
    uint8_t testb;
	GPIOB0_OUT();	
    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;
        dat=dat>>1;
        if (testb) //写1
        {
            GPIO_ResetBits(GPIOB, GPIO_Pin_0); 
            Delay_us(2);                            
            GPIO_SetBits(GPIOB, GPIO_Pin_0); 
            Delay_us(60);             
        }
        else //写0
        {
            GPIO_ResetBits(GPIOB, GPIO_Pin_0); 
            Delay_us(60);             
            GPIO_SetBits(GPIOB, GPIO_Pin_0);
            Delay_us(2);                          
        }
    }
}

//开始温度转换
void DS18B20_Start(void) 
{   						               
    DS18B20_Rst();	   
	DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);	
    DS18B20_Write_Byte(0x44);	
} 

//从DS18B20得到温度值
//精度：0.1
//返回值：温度值 （-550~1250） 
short DS18B20_Get_Temp(void)
{
    uint8_t temp;
    uint8_t TL,TH;
	short tem;
    DS18B20_Start ();  		
    DS18B20_Rst();
    DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);	
    DS18B20_Write_Byte(0xbe);		    
    TL=DS18B20_Read_Byte(); 	 
    TH=DS18B20_Read_Byte(); 	
	    	  
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
        temp=0;					//温度为负  
    }
	else temp=1;				//温度为正	  	  
    tem=TH; 					//获得高八位
    tem<<=8;    
    tem+=TL;					//获得低八位
    tem=(float)tem*0.625;		//转换     
	if(temp) return tem; 		//返回温度值
	else return -tem;    
}




